import React from 'react'
import {
  View,
  Text,
  Dimensions,
  StatusBar,
  TouchableOpacity,
  ScrollView,
  FlatList,
  Image
} from 'react-native'

import { toJS } from 'mobx'
import { Placeholder, PlaceholderLine, Shine } from 'rn-placeholder'
import { useNavigation } from '@react-navigation/native'
import Icon from 'react-native-vector-icons/Ionicons'
import { observer, useLocalObservable } from 'mobx-react-lite'
import { useStores } from '../stores'
import { Gap, SearchHeader, Snackbar, TagButton } from '../views'
import i18n from '../i18n'
import BookItem from '../views/BookItem'
import CollapsibleText from '../views/CollapsibleText'
import { shortly5 } from '../utils/text'


let statusBarHeight = 0
if (Platform.OS == 'ios') {
  statusBarHeight = StatusBar.currentHeight || 45
}

const { windowWidth } = Dimensions.get('window')

const LoadingCard = observer(() => {
  const { appearance: ap } = useStores()
  return (
    <Placeholder
      Animation={Shine}
      style={{ flex: 1, padding: 30, paddingTop: 60 }}
    >
      <PlaceholderLine width={20} />
      <PlaceholderLine width={40} />
      <PlaceholderLine width={60} />
      <PlaceholderLine />

      <PlaceholderLine width={20} />
      <PlaceholderLine width={40} />
      <PlaceholderLine width={60} />
      <PlaceholderLine />

    </Placeholder>
  )
})

const HistoryCard = observer(({ history, onSummit = () => { } }) => {
  history = history.map(it => it.toString())
  const { appearance: ap, search } = useStores()
  return (
    <View style={{ padding: 12 }}>
      <View style={{ paddingBottom: 12, flexDirection: 'row', alignItems: 'center' }}>
        <Text style={{ color: ap.theme.second, fontSize: 16 }}>
          {i18n.t('searchHistory')}
        </Text>
        <TouchableOpacity style={{ marginLeft: 12 }}
          onPress={() => search.clearHistory()}>
          <Text style={{ color: ap.theme.active }}>{i18n.t('searchHistoryClear')}</Text>
        </TouchableOpacity>
      </View>
      <View style={{ flex: 1, flexWrap: 'wrap', flexDirection: 'row' }}>
        {
          history.map(it => (
            <View style={{ marginBottom: 6 }}>
              <TagButton
                title={it}
                backgroundColor={ap.theme.surface}
                color={ap.theme.weak}
                onPress={() => onSummit(it)} />
            </View>
          ))
        }
      </View>
    </View>
  )
})

const HotspotCard = observer(({ books = [] }) => {
  const { appearance: ap, bookApi } = useStores()
  const navigation = useNavigation()
  return (
    <View style={{ ...styles.resultCard, flex: 1, backgroundColor: ap.theme.surface }}>
      <View style={{ padding: 14 }}>
        <View style={{ paddingBottom: 12 }}>
          <Text style={{ color: ap.theme.second, fontSize: 16 }}>{i18n.t('searchHotspot')}</Text>
        </View>
        <View style={{ flexDirection: 'row', flexWrap: 'wrap', justifyContent: 'space-between' }}>
          {
            books && books.map(it => (
              <TouchableOpacity
                onPress={() => navigation.push('Book', { title: it.name, _id: it._id })}
                style={{ paddingBottom: 16, alignItems: 'center', marginRight: 5 }}
              >
                <Image
                  source={{ uri: bookApi.getCoverUrl(it.cover) }}
                  style={{ width: 113 * 0.6, height: 150 * 0.6, borderRadius: 6 }}
                />
                <Gap gap={3} />
                <Text style={{ color: ap.theme.second, fontSize: 12 }}>{shortly5(it.name)}</Text>
              </TouchableOpacity>
            ))
          }
        </View>
      </View>
    </View>
  )
})

const SearchResultBookCard = observer(({ title, books = [] }) => {
  const { appearance: ap } = useStores()
  if (!books.length) {
    return <></>
  }
  return (
    <View style={{ ...styles.hotspotContainer, padding: 12 }}>
      <View style={{ paddingBottom: 12 }}>
        <Text style={{ color: ap.theme.second, fontSize: 16 }}>{title}</Text>
      </View>
      <View>
        {
          books.map(it => (
            <BookItem book={toJS(it)} style={{ paddingBottom: 6, paddingTop: 4 }} />
          ))
        }
      </View>
    </View>
  )
})


const SearchResultArticleCard = observer(({ articles }) => {
  const { appearance: ap } = useStores()
  const navigation = useNavigation()
  return (
    <View style={{ padding: 12 }}>
      <View style={{ paddingBottom: 8 }}>
        <Text style={{ color: ap.theme.second, fontSize: 16 }}>
          {i18n.t('searchResult')}-{i18n.t('article')}
        </Text>
      </View>
      {
        articles.map(it => (
          <TouchableOpacity
            style={{ paddingBottom: 10, paddingTop: 10 }}
            onPress={() => navigation.push('Reader', { type: 'article', _id: it._id})}
          >
            <Text style={{ color: ap.theme.active }}>《{it.name}》</Text>
            <Gap gap={4} />
            { it.summary &&
              <CollapsibleText
                style={{ flex: 1, color: ap.theme.second, fontSize: 12 }}
                numberOfLines={3}
                labels={[i18n.t('expand'), i18n.t('collapse')]}>
                {it.summary}
              </CollapsibleText> || <></>
            }
          </TouchableOpacity>
        ))
      }
    </View>
  )
})

const SearchResultAuthorCard = observer(({ authors }) => {
  const { appearance: ap } = useStores()
  const navigation = useNavigation()
  return (
    <View style={{ padding: 12 }}>
      <View style={{ paddingBottom: 8 }}>
        <Text style={{ color: ap.theme.second, fontSize: 16 }}>
          {i18n.t('searchResult')}-{i18n.t('writer')}</Text>
      </View>
      {
        authors.map(it => (
          <TouchableOpacity
            style={{ paddingBottom: 10, paddingTop: 10 }}
            key={it._id}
            onPress={() => navigation.push('BookList', { data: it, key: 'author' })}>
            <Text style={{ color: ap.theme.active }}>{it.name}</Text>
            <Gap gap={4} />
            { it.info &&
              <CollapsibleText
                style={{ flex: 1, color: ap.theme.second, fontSize: 12 }}
                numberOfLines={3}
                labels={[i18n.t('expand'), i18n.t('collapse')]}>
                {it.info}
              </CollapsibleText> || <></>
            }
          </TouchableOpacity>
        ))
      }
    </View>
  )
})

const SearchResultCard = observer(({ books, authors, articles }) => {
  const { appearance: ap } = useStores()
  return (
    <View>
      {
        authors && authors.length &&
        <View style={{ ...styles.resultCard, backgroundColor: ap.theme.surface }}>
          <SearchResultAuthorCard authors={authors} />
        </View> ||
        <></>
      }
      <Gap gap={14} />

      {
        books && books.length &&
        <View style={{ ...styles.resultCard, backgroundColor: ap.theme.surface }}>
          <SearchResultBookCard books={books}
            title={`${i18n.t('searchResult')}-${i18n.t('book')}`} />
        </View> ||
        <></>
      }
      
      <Gap gap={14} />
      {
        articles && articles.length &&
        <View style={{ ...styles.resultCard, backgroundColor: ap.theme.surface }}>
          <SearchResultArticleCard articles={articles} />
        </View> ||
        <></>
      }
    </View>
  )
})

export default observer(({ navigation }) => {
  const { appearance: ap, bookApi, search } = useStores()

  const states = useLocalObservable(() => ({
    searchResult: null,
    query: '',
    input: '',
    loading: false,
    setSearchResult(result) {
      this.searchResult = result
    },
    clear() {
      this.searchResult = null
    },
    setQuery(query) {
      this.query = query
    },

    setInput(txt) {
      this.input = txt
    },

    setLoading(loading) {
      this.loading = loading
    }
  }))

  const summit = txt => {
    txt = txt || states.input
    if (!txt) {
      txt = search.placeholder
    }
    states.setInput(txt)
    states.setQuery(txt)
    states.setLoading(true)

    search.appendHistory(txt)
    bookApi.fetchSearchResult(txt).then(data => {
      states.setLoading(false)
      const { books, authors, articles } = data
      states.setSearchResult({ books, authors, articles })
    }).catch(err => Snackbar.error(err.toString()))
  }

  React.useLayoutEffect(() => {
    navigation.setOptions({
      title: i18n.t('search')
    })
  })

  return (
    <View style={{ ...styles.container, backgroundColor: ap.theme.background }}>
      <View style={{ flex: 1 }}>
        {states.loading &&
          <LoadingCard /> ||
          <ScrollView style={{ ...styles.mainContainer }}>
            {
              !states.searchResult &&
              <>
                <HistoryCard history={toJS(search.history)} onSummit={summit} />
                <HotspotCard title={i18n.t('searchHotspot')} books={search.hotspot} />
              </> ||
              <SearchResultCard
                books={states.searchResult.books}
                authors={states.searchResult.authors}
                articles={states.searchResult.articles}
              />
            }
          </ScrollView>
        }
        <SearchHeader
          real={true}
          value={states.query}
          onSummit={() => summit()}
          onClear={() => states.clear()}
          onChangeText={txt => states.setInput(txt)}
          input={states.input} />
      </View>

    </View>
  )
})

const styles = {
  container: {
    flex: 1,
    paddingTop: statusBarHeight,
  },

  mainContainer: {
    flex: 1,
    marginTop: 44,
    padding: 12,
  },

  hotspotContainer: {
    borderRadius: 6,
  },

  resultCard: {
    borderRadius: 6,
  }
}